package org.jeecg.modules.demo.cashier;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.allinpay.sdk.bean.OpenResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.modules.demo.util.Allinpay;
import org.jeecg.modules.demo.util.ProfitUtil;
import org.jeecg.modules.demo.weixin.dto.PayDto;
import org.jeecg.modules.demo.weixin.dto.ProfitSharingDto;
import org.jeecg.modules.demo.weixin.dto.RefundDto;
import org.jeecg.modules.demo.weixin.entity.*;
import org.jeecg.modules.demo.weixin.merchantpay.service.IMerchantPayService;
import org.jeecg.modules.demo.weixin.payorder.service.IPayOrderService;
import org.jeecg.modules.demo.weixin.smtprofitsharingreceiver.service.ISmtProfitsharingReceiverService;
import org.jeecg.modules.demo.weixin.smtsharingmember.service.ISmtSharingMemberService;
import org.jeecg.modules.demo.weixin.smtsplitrulecom.service.ISmtSplitRuleComService;
import org.jeecg.modules.demo.weixin.util.PayConstants;
import org.jeecg.modules.demo.weixin.vo.ProfitVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description: 收银台 扫码支付接口
 * @Author: jeecg-boot
 * @Date: 2023-10-23
 * @Version: V1.0
 */
@RestController
@RequestMapping("/weixin/profitSharing")
@Slf4j
public class ProfitSharingController {

    @Autowired
    private IPayOrderService payOrderService;


    @Autowired
    private IMerchantPayService merchantPayService;


    private static CloseableHttpClient httpClient;

    @Autowired
    private ISmtProfitsharingReceiverService smtProfitsharingReceiverService;

    @Autowired
    private ISmtSharingMemberService smtSharingMemberService;



//    /**
//     * 微信分账分账
//     *
//     * @param profitSharingDto
//     * @return
//     */
//    @SneakyThrows
//    @PostMapping("/sharing")
//    public Result<?> sharing(@RequestBody ProfitSharingDto profitSharingDto, HttpServletRequest request) {
//        //根据商家id查询商家配置的支付信息
//        QueryWrapper<MerchantPay> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("merchant_id", Integer.valueOf(profitSharingDto.getMerId()));
//        MerchantPay merchantPay = merchantPayService.getOne(queryWrapper);
//        //判断订单
//        PayOrder payOrder = payOrderService.getById(profitSharingDto.getOutTradeNo());
//        if (!payOrder.getPayStatus().equals("2")) {
//            return Result.error(606, "当前订单未支付完成或者已经退款！");
//        }
//        JSONObject sharing = ProfitUtil.sharing(profitSharingDto, payOrder, merchantPay.getMchId());
//        if (sharing == null) {
//            return Result.error("分账失败");
//        }
//        //获取每一个分账接收方对应的结果
//        List<ProfitVo> profitVos = sharing.getJSONArray("receivers").stream().map(item -> JSON.parseObject(((JSONObject) item).toString(), ProfitVo.class)).collect(Collectors.toList());
//        profitVos.forEach(profitVo -> {
//            SmtSharingMember member = new SmtSharingMember();
//            member.setTransactionId(sharing.getString("transaction_id"));
//            member.setOutOrderNo(sharing.getString("out_order_no"));
//            member.setSubMchid(sharing.getString("sub_mchid"));
//            member.setOrderId(sharing.getString("order_id"));
//            member.setAccount(profitVo.getAccount());
//            member.setAmount(profitVo.getAmount());
//            member.setState(profitVo.getResult());
//            member.setDescription(profitVo.getDescription());
//            //失败的时候才会返回
//            member.setFailReason(profitVo.getFailReason());
//            member.setType(profitVo.getType());
//            member.setDetailId(profitVo.getDetailId());
//            member.setFinishTime(profitVo.getFinishTime());
//            smtSharingMemberService.save(member);
//        });
//        return Result.ok("分账成功");
//    }

    /**
     * 微信分账添加分账接收方
     *
     * @param req
     * @return
     */
    @SneakyThrows
    @PostMapping("/addShar")
    public Result<?> addShar(@RequestBody SmtProfitsharingReceiver req, HttpServletRequest request) {

        //根据商家id查询商家配置的支付信息
        QueryWrapper<MerchantPay> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("merchant_id", Integer.valueOf(req.getMerchantId()));
        MerchantPay merchantPay = merchantPayService.getOne(queryWrapper);
        if (merchantPay == null && StringUtils.isBlank(merchantPay.getSpecialSubMerchants())) {
            return Result.error("该商户不是代理商 请重新传入");
        }
        JSONObject result = ProfitUtil.addShar(merchantPay.getSpecialSubMerchants(), req.getType(), req.getMerName(), req.getAccount(), req.getRelationType());
        if (result == null) {
            Result.error("添加失败，请重新审核信息后添加！");
        }
        req.setAseName(result.getString("name"));
        req.setRelationType(result.getString("relation_type"));
        req.setSubMchid(result.getString("sub_mchid"));
        req.setType(result.getString("type"));
        req.setAccount(result.getString("account"));
        smtProfitsharingReceiverService.save(req);
        return Result.ok("添加分账接收方成功");
    }

    @Autowired
    private ISmtSplitRuleComService smtSplitRuleComService;
    /**
     * 微信分账删除分账接收方
     *
     * @return
     */
    @SneakyThrows
    @GetMapping("/delProfitsharing")
    public Result<?> delProfitsharing(@RequestParam Integer id) {
        SmtSplitRuleCom receiver = smtSplitRuleComService.getById(id);
        if (receiver == null) {
            return Result.error("该代理商不存在！");
        }
        JSONObject del = ProfitUtil.del(receiver.getSubMchid(), receiver.getType(), receiver.getComId());
        if (del == null) {
            return Result.error("删除分账方失败");
        }
        smtSplitRuleComService.removeById(id);
        return Result.ok("结束分账接收方关系成功");
    }

    /**
     * 微信分账查询分账状态
     *
     * @param profitSharingDto
     * @return
     */
    @SneakyThrows
    @PostMapping("/querySharing")
    public Result<?> querySharing(@RequestBody ProfitSharingDto profitSharingDto, HttpServletRequest request) {
        //根据商家id查询商家配置的支付信息
        QueryWrapper<MerchantPay> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("merchant_id", Integer.valueOf(profitSharingDto.getMerId()));
        MerchantPay merchantPay = merchantPayService.getOne(queryWrapper);
        //判断订单
        PayOrder payOrder = payOrderService.getById(profitSharingDto.getOutTradeNo());
        if (!payOrder.getPayStatus().equals("2")) {
            return Result.error(606, "当前订单未支付完成或者已经退款！");
        }
//        //微信支付的单位是分，要转换一下
        String amount = String.valueOf(payOrder.getPayPrice().multiply(BigDecimal.valueOf(100)).multiply(BigDecimal.valueOf(0.3)).intValue());
        //查询分账信息
        String url = "https://api.mch.weixin.qq.com/v3/profitsharing/orders/{0}?sub_mchid={1}&transaction_id={2}";
        String get = url.replace("{0}", String.valueOf(payOrder.getId())).replace("{1}", merchantPay.getSpecialSubMerchants()).replace("{2}", payOrder.getTransactionId());

        HttpGet httpGet = new HttpGet(get);
//        post.addHeader("Authorization", "WECHATPAY2-SHA256-RSA2048" + " " + strToken);
        httpGet.addHeader("Accept", "application/json");
//        post.addHeader("Wechatpay-Serial", PayConstants.MCH_SERIAL_NO);
        httpGet.setHeader("Content-Type", "application/json; charset=utf-8");
        CloseableHttpResponse response = null;
        response = httpClient.execute(httpGet);
        String content = EntityUtils.toString(response.getEntity());
        JSONObject result = JSONObject.parseObject(content);
        return Result.ok(result);
    }


//    /**
//     * 退回分账金额   需要商户在微信支付开启分账退还   一般情况下 分账的金额都是已经不退换的订单
//     *
//     * @param profitSharingDto
//     * @return
//     */
//    @SneakyThrows
//    @PostMapping("/refundSharing")
//    public Result<?> refundSharing(@RequestBody ProfitSharingDto profitSharingDto, HttpServletRequest request) {
//        this.mchSetup();
//        //根据商家id查询商家配置的支付信息
//        QueryWrapper<MerchantPay> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("merchant_id", Integer.valueOf(profitSharingDto.getMerId()));
//        MerchantPay merchantPay = merchantPayService.getOne(queryWrapper);
//        //判断订单
//        PayOrder payOrder = payOrderService.getById(profitSharingDto.getOutTradeNo());
//        if (!payOrder.getPayStatus().equals("2")) {
//            return Result.error(606, "当前订单未支付完成或者已经退款！");
//        }
////        //微信支付的单位是分，要转换一下
//        String amount = String.valueOf(payOrder.getPayPrice().multiply(BigDecimal.valueOf(100)).multiply(BigDecimal.valueOf(0.3)).intValue());
//
//        JSONObject jsonParam = new JSONObject();
//        jsonParam.put("sub_mchid", merchantPay.getSpecialSubMerchants());
//        jsonParam.put("out_order_no", "36000100912023111781150127189");
////        jsonParam.put("order_id", "36000100912023111781150127189");
//        jsonParam.put("out_return_no", String.valueOf(payOrder.getId()));
//        jsonParam.put("return_mchid", PayConstants.MCH_ID_SERVICE);
//        jsonParam.put("amount", Integer.parseInt(amount));
//        jsonParam.put("description", "回退");
//        String url = "https://api.mch.weixin.qq.com/v3/profitsharing/return-orders";
//        HttpPost post = new HttpPost(url);
////        post.addHeader("Authorization", "WECHATPAY2-SHA256-RSA2048" + " " + strToken);
//        post.addHeader("Accept", "application/json");
////        post.addHeader("Wechatpay-Serial", PayConstants.MCH_SERIAL_NO);
//        post.setHeader("Content-Type", "application/json; charset=utf-8");
//        StringEntity postingString = new StringEntity(JSONObject.toJSONString(jsonParam), "utf-8");
//        post.setEntity(postingString);
//        CloseableHttpResponse response = null;
//        response = httpClient.execute(post);
//        String content = EntityUtils.toString(response.getEntity());
//        JSONObject jsonObject = JSONObject.parseObject(content);
//        return Result.ok(jsonObject);
//
//    }


    /**
     * 微信分账 分页列表查询
     *
     * @param smtSharingMember
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    @ApiOperation(value = "分账记录表-分页列表查询", notes = "分账记录表-分页列表查询")
    @GetMapping(value = "/listMember")
    public Result<IPage<SmtSharingMember>> queryPageList(SmtSharingMember smtSharingMember,
                                                         @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                         @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                         HttpServletRequest req) {
        QueryWrapper<SmtSharingMember> queryWrapper = QueryGenerator.initQueryWrapper(smtSharingMember, req.getParameterMap());
        Page<SmtSharingMember> page = new Page<SmtSharingMember>(pageNo, pageSize);
        IPage<SmtSharingMember> pageList = smtSharingMemberService.page(page, queryWrapper);
        if (CollectionUtils.isEmpty(pageList.getRecords())) {
            return Result.ok(pageList);
        }
        pageList.getRecords().forEach(smtSharingMember1 -> {
            if (smtSharingMember1.getState().equals("PENDING")) {
                JSONObject sharing = ProfitUtil.querySharing(smtSharingMember1.getOutOrderNo(), smtSharingMember1.getSubMchid(), smtSharingMember1.getTransactionId());
                if (sharing != null) {
                    smtSharingMemberService.updateState(smtSharingMember1, sharing);
                }
            }
        });
        return Result.OK(pageList);
    }


    /**
     * 微信分账分页列表查询
     *
     * @param smtProfitsharingReceiver
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    @ApiOperation(value = "添加分账接收方表-分页列表查询", notes = "添加分账接收方表-分页列表查询")
    @GetMapping(value = "/listReceiver")
    public Result<IPage<SmtProfitsharingReceiver>> queryPageList(SmtProfitsharingReceiver smtProfitsharingReceiver,
                                                                 @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                                 @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                                 HttpServletRequest req) {
        LambdaQueryWrapper<MerchantPay> payLambdaQueryWrapper = new LambdaQueryWrapper<>();
        payLambdaQueryWrapper.eq(MerchantPay::getMerchantId, Integer.valueOf(smtProfitsharingReceiver.getMerchantId()));

        MerchantPay payServiceOne = merchantPayService.getOne(payLambdaQueryWrapper);
        if (payServiceOne == null) {
            return Result.error("商家不是代理商");
        }

        QueryWrapper<SmtProfitsharingReceiver> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("sub_mchid", payServiceOne.getSpecialSubMerchants());
        if (StringUtils.isNotBlank(smtProfitsharingReceiver.getMerName())) {
            queryWrapper.like("mer_name", smtProfitsharingReceiver.getMerName());
        }
        Page<SmtProfitsharingReceiver> page = new Page<SmtProfitsharingReceiver>(pageNo, pageSize);
        IPage<SmtProfitsharingReceiver> pageList = smtProfitsharingReceiverService.page(page, queryWrapper);
        return Result.OK(pageList);
    }


    @PostMapping(value = "/consumeApply")
    public Object consumeApply(@RequestBody PayDto payDto) {
        return Allinpay.consumeApply(payDto, payDto.getYuYueId());
//        return null;
    }

    @PostMapping(value = "/agentCollectApply")
    public Object agentCollectApply(@RequestBody PayDto payDto) {
        return Allinpay.agentCollectApply(payDto, payDto.getYuYueId());
//        return null;
    }


    @PostMapping(value = "/refund")
    public JSONObject refund(@RequestBody RefundDto refundDto) {
        return Allinpay.refund(refundDto.getOutTradeNo(),refundDto.getTransactionId(),refundDto.getRefundPrice());
    }


    @GetMapping(value = "/refundSplit")
    public OpenResponse refundSplit() {
        return Allinpay.refundSplit();
    }

    @GetMapping(value = "/queryBalance")
    public OpenResponse queryBalance() {
        return Allinpay.queryBalance();
    }


    @GetMapping(value = "/signalAgentPay")
    public OpenResponse signalAgentPay() {
        return Allinpay.signalAgentPay();
    }


//    @GetMapping(value = "/setCompanyInfo")
//    public OpenResponse setCompanyInfo() {
//        return Allinpay.setCompanyInfo();
//    }

    /**
     * 创建会员
     */
    @GetMapping(value = "/createMember")
    public JSONObject createMember(@RequestBody String biz, @RequestParam Long type) {
        return Allinpay.createMember(biz,type);
    }

    /**
     * 提现
     */
    @GetMapping(value = "/withdrawApply")
    public OpenResponse withdrawApply() {
        return Allinpay.withdrawApply();
    }

    /**
     * 绑定银行卡申请
     *
     * @return
     */
    @GetMapping(value = "/applyBindBankCard")
    public OpenResponse applyBindBankCard() {
        return Allinpay.applyBindBankCard();
    }

    /**
     * 个人用户实名认证
     *
     * @return
     */
    @GetMapping(value = "/setRealName")
    public OpenResponse setRealName() {
        return Allinpay.setRealName();
    }

    /**
     * 绑定银行卡确定
     *
     * @return
     */
    @GetMapping(value = "/bindBankCard")
    public OpenResponse bindBankCard() {
        return Allinpay.bindBankCard();
    }

    @GetMapping(value = "/bindPhone")
    public JSONObject bindPhone(String bizUser, String phone, String verificationCode) {
        return Allinpay.bindPhone(bizUser,phone,verificationCode);
    }

    @GetMapping(value = "/idcardCollect")
    public JSONObject idcardCollect(String imageUrl) {
        return Allinpay.idcardCollect(imageUrl);
    }


    @GetMapping(value = "/getMemberInfo")
    public OpenResponse getMemberInfo() {
        return Allinpay.getMemberInfo();
    }

    @GetMapping(value = "/verifyResult")
    public OpenResponse verifyResult() {
        return Allinpay.verifyResult();
    }

    @GetMapping(value = "/signAcctProtocol")
    public String signAcctProtocol() {
        return Allinpay.signAcctProtocol();
    }

    /**
     * 待支付   24 小时订单自动取消接口
     *
     * @param payDto
     * @return
     */
//    @SneakyThrows
//    @PostMapping("/cancellation")
//    public String cancellation(@RequestBody PayDto payDto, HttpServletResponse response) {
////        System.out.println(payDto.getImageUrl());
//        URL url = new URL(payDto.getImageUrl());
//        response.encodeURL(payDto.getImageUrl());
//        URLConnection urlConnection = url.openConnection();
//        BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
//        String line;
//        StringBuilder content = new StringBuilder();
//        while ((line = reader.readLine()) != null) {
//            content.append(line);
//        }
//        reader.close();
//        String base64String = Base64.getEncoder().encodeToString(content.toString().getBytes());
//        return base64String;
//    }
//    @SneakyThrows
//    @PostMapping("/base64ToFile")
//    public static Boolean base64ToFile(@RequestBody PayDto payDto) {
//        byte[] buffer;
//        try {
//            payDto.setBase64(Allinpay.ImageBase64(payDto.getImageUrl()));
//            buffer = org.springframework.util.Base64Utils.decodeFromString(payDto.getBase64());
//            FileOutputStream out = new FileOutputStream(payDto.getPath());
//            out.write(buffer);
//            out.close();
//            return true;
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return null;
//    }


//    @SneakyThrows
//    @PostMapping("/cancellation")
//    public static Object cancellation(@RequestBody PayDto payDto) {
//        byte[] buffer;
//        try {
////            buffer = new BASE64Decoder().decodeBuffer(payDto.getBase64());
////            FileOutputStream out = new FileOutputStream(payDto.getPath());
////            out.write(buffer);
////            out.close();
//            return Allinpay.ImageBase64(payDto.getImageUrl());
////            return true;
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return null;
//    }



//    /**
//     * 查询订单结果
//     * @return
//     */
//    @GetMapping(value = "/query")
//    public OpenResponse query(){
//        configClient();
//        BizParameter param = new BizParameter();
//        param.put("orderNo", "1732221663170338816");
//        param.put("bizOrderNo", "789522336512322567");
//        param.put("amount", 10);
//        param.put("buyerBizUserId", "yc0001");
//        //状态“OK”标识支付成功；“pending”表示进行中（中间状态）   “error”表示支付失败；
//        param.put("status", "OK");
//        try {
//            final OpenResponse response = client.execute("allinpay.yunst.orderService.pay", param);
//            return  response;
//        } catch (final Exception e) {
//            e.printStackTrace();
//        }
//        return null;
//    }

    /**
     * 查询状态
     *
     * @return
     */
    @GetMapping(value = "/getOrderStatus")
    public JSONObject getOrderStatus() {
        return Allinpay.getOrderDetail("111111111","22222222222222222");
//        return null;
    }


    /**
     * 订单分账明细查询
     */
    @GetMapping(value = "/getOrderSplitRuleListDetail")
    public JSONObject getOrderSplitRuleListDetail() {
        return Allinpay.getOrderSplitRuleListDetail();
    }


}
